home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / NEWS.C < prev    next >
C/C++ Source or Header  |  1989-12-31  |  5KB  |  256 lines

  1. #include "config.h"
  2. #include "news.h"
  3.  
  4. export retry_on_error = 0;
  5.  
  6.  
  7. FILE *open_news_article(art, modes, buffer1, buffer2)
  8. article_header         *art;
  9. int             modes;
  10. news_header_buffer    buffer1, buffer2;
  11. {
  12.     char *body;
  13.     char *digest_buffer;
  14.     char *parse_header(), **art_hdr_field();
  15.     struct stat statb;
  16.     int retry;
  17.     FILE *f;
  18. #ifdef NNTP
  19.     FILE *nntp_get_article();
  20. #endif /* NNTP */
  21.  
  22.     if (art->flag & A_FOLDER) {
  23.     f = open_file(group_path_name, OPEN_READ);
  24.     if (f == NULL) return NULL;
  25.     fseek(f, art->hpos, 0);
  26. #ifdef NNTP    
  27.     } else
  28.     if (use_nntp) {
  29.     f = nntp_get_article(art->a_number);
  30.     if (f == NULL) return NULL;
  31. #endif /* NNTP */
  32.     } else {
  33.     sprintf(group_file_name, "%d", art->a_number);
  34.  
  35.     retry = retry_on_error;
  36.     while ((f = open_file(group_path_name, OPEN_READ)) == NULL)
  37.         if (--retry < 0) return NULL;
  38.  
  39.     /* necessary because empty files wreak havoc */
  40.     if (fstat(fileno(f), &statb) < 0 ||
  41.         statb.st_size < art->lpos || statb.st_size <= (off_t)0) {
  42.         fclose(f);
  43.         return NULL;
  44.     }
  45.     }
  46.     
  47.     digest_buffer = buffer1;
  48.     
  49.     if (modes & FILL_NEWS_HEADER) {
  50.  
  51.     news.ng_from     = NULL;
  52.     news.ng_reply     = NULL;
  53.     news.ng_name     = NULL;
  54.     news.ng_subj     = NULL;
  55.     news.ng_groups     = NULL;
  56.     news.ng_ref     = NULL;
  57.     news.ng_bref     = NULL;
  58.  
  59.     news.ng_xlines     = NULL;
  60.  
  61.     if (modes & GET_ALL_FIELDS) {
  62.         news.ng_path     = NULL;
  63.         news.ng_reply     = NULL;
  64.         news.ng_ident     = NULL;
  65.         news.ng_follow     = NULL;
  66.         news.ng_keyw     = NULL;
  67.         news.ng_dist     = NULL;
  68.         news.ng_org     = NULL;
  69.         news.ng_appr     = NULL;
  70.         news.ng_summ    = NULL;
  71.         news.ng_date    = NULL;
  72.         news.ng_rdate    = NULL;
  73.     }
  74.  
  75.     if (modes & GET_DATE_ONLY)
  76.         news.ng_date    = NULL;
  77.     
  78.     body = parse_header(f, art_hdr_field, modes, buffer1);
  79.     
  80.     news.ng_lines = news.ng_xlines ? atoi(news.ng_xlines) : -1;
  81.     
  82.     if (modes & FILL_OFFSETS) {
  83.         art->fpos = news.ng_fpos = ftell(f);
  84.  
  85.         fseek(f, (off_t)0, 2);
  86.         news.ng_lpos = ftell(f);
  87.     }
  88.  
  89.     news.ng_flag = 0;
  90.  
  91.     if (news.ng_appr) news.ng_flag |= N_MODERATED;
  92.     
  93.     if (modes & DIGEST_CHECK && is_digest(body))
  94.         news.ng_flag |= N_DIGEST;
  95.     
  96.     digest_buffer = buffer2;
  97.     }
  98.  
  99.     if (modes & FILL_DIGEST_HEADER) {
  100.     fseek(f, art->hpos, 0);
  101.     parse_digest_header(f, modes & GET_ALL_FIELDS, digest_buffer);
  102.     }
  103.  
  104.     fseek(f, (modes & SKIP_HEADER) ? art->fpos : art->hpos, 0);
  105.     
  106.     return f;
  107. }
  108.  
  109.  
  110.  
  111. char *parse_header(f, hdr_field, modes, hdrbuf)
  112. FILE             *f;
  113. char             **(*hdr_field)();
  114. int             modes;
  115. news_header_buffer    hdrbuf;
  116. {
  117.     register char *bp, **fptr;
  118.     int siz, all, date_only;
  119.     off_t pos;
  120.     
  121.     pos = ftell(f);
  122.  
  123. /* read first NEWS_HEADER_BUFFER bytes (should be more than enough) */
  124.  
  125.     all     = modes & GET_ALL_FIELDS;
  126.     date_only     = modes & GET_DATE_ONLY;
  127.     
  128.     siz = fread(hdrbuf, sizeof(char), NEWS_HEADER_BUFFER, f);
  129.     
  130.     bp = hdrbuf;
  131.     bp[siz-1] = NUL;
  132.     
  133.     /* decode subarticle header */
  134.     while (*bp) {
  135.  
  136.     if (*bp == NL) {    /* empty line following header */
  137.         ++bp;
  138.         fseek(f, pos + (bp - hdrbuf), 0);
  139.         return bp;
  140.     }
  141.     
  142.     if (*bp == SP) {    /* for comp.ai.neural-nets digests */
  143.         bp++;        /* which have <NL><space><NL> after header */
  144.         continue;
  145.     }
  146.  
  147.     if (date_only && *bp != 'D')
  148.         fptr = NULL;
  149.     else
  150.         if (fptr = (*hdr_field)(bp, all)) {
  151.         while (*bp && *bp != ':' && isascii(*bp) && !isspace(*bp))
  152.             bp++;
  153.         bp++;
  154.         while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++;
  155.         *fptr = bp;
  156.         }
  157.     while (*bp && *bp != NL) bp++;
  158.     if (fptr && bp == *fptr) *fptr = NULL;
  159.     if (*bp) *bp++ = NUL;
  160.     }
  161.  
  162.     return bp;
  163. }
  164.  
  165.  
  166. static char **art_hdr_field(lp, all)
  167. register char *lp;
  168. int all;
  169. {
  170.     
  171. #define check(name, lgt, field) \
  172.     if (strncmp(name, lp, lgt) == 0) return &news.field
  173.  
  174.     switch (*lp++) {
  175.  
  176.      case 'A':
  177.     if (!all) break;
  178.     check("pproved: ",     9, ng_appr);
  179.     break;
  180.  
  181.      case 'B':
  182.     check("ack-eferences: ",15, ng_bref);
  183.     break;
  184.  
  185.      case 'D':
  186.     check("ate: ",          5, ng_date);
  187.     if (!all) break;
  188.     check("ate-Received: ",    14, ng_rdate);
  189.     check("istribution: ",     13, ng_dist);
  190.     break;
  191.  
  192.      case 'F':
  193.     check("rom: ",         5, ng_from);
  194.     if (!all) break;
  195.     check("ollowup-To: ",    12, ng_follow);
  196.     break;
  197.  
  198.      case 'K':
  199.     if (!all) break;
  200.     check("eywords: ",     9, ng_keyw);
  201.     break;
  202.  
  203.      case 'L':
  204.     check("ines: ",          6, ng_xlines);
  205.     break;
  206.  
  207.      case 'M':
  208.     if (!all) break;
  209.     check("essage-ID: ",    11, ng_ident);
  210.     break;
  211.  
  212.      case 'N':
  213.     check("ewsgroups: ",    11, ng_groups);
  214.     break;
  215.  
  216.      case 'O':
  217.     if (!all) break;
  218.     check("rganization: ",    13, ng_org);
  219.     check("rganisation: ",    13, ng_org);
  220.     break;
  221.  
  222.      case 'P':
  223.     if (!all) break;
  224.     check("ath: ",         5, ng_path);
  225.     break;
  226.  
  227.      case 'R':
  228.     check("eply-To: ",     9, ng_reply);
  229.     check("eferences: ",    11, ng_ref);
  230.     break;
  231.  
  232.      case 'S':
  233.     check("ubject: ",     8, ng_subj);
  234.     if (news.ng_from == NULL)
  235.         check("ender: ",     7, ng_from);
  236.     if (!all) break;
  237.     check("ummary: ",     8, ng_summ);
  238.     break;
  239.  
  240.      case 'T':
  241.     check("itle: ",          6, ng_subj);
  242.     break;
  243.     }
  244.  
  245.     return NULL;
  246.  
  247. #undef check
  248. }
  249.  
  250.  
  251. is_header_line(line)
  252. char *line;
  253. {
  254.     return art_hdr_field(line, 0) != (char **)NULL;
  255. }
  256.